home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / comm / net / rhslip38_9_030.lha / rhslip / src / cslip.h < prev    next >
C/C++ Source or Header  |  1994-01-26  |  11KB  |  326 lines

  1. /* $Id: cslip.h,v 1.1 1993/08/17 00:00:00 rhialto Exp $
  2.  *
  3.  * The code in this file is derived from and very similar to the example
  4.  * implementation provided in RFC 1144, and is therefore sort-of covered
  5.  * by its copyright:
  6.  *
  7.  * Copyright (C) 1989 Regents of the University of California.
  8.  *
  9.  * modified for KA9Q Internet Software Package by
  10.  * Katie Stevens (dkstevens@ucdavis.edu)
  11.  * University of California, Davis
  12.  * Computing Services
  13.  *    - 01-31-90    initial adaptation
  14.  *
  15.  *    - Feb 1991    Bill_Simpson@um.cc.umich.edu
  16.  *            variable number of conversation slots
  17.  *            allow zero or one slots
  18.  *            separate routines
  19.  *            status display
  20.  *
  21.  * This adaptation (for rhcslip.device) by Olaf 'Rhialto' Seibert.
  22.  */
  23.  
  24. /*
  25.  * Compressed packet format:
  26.  *
  27.  * The first octet contains the packet type (top 3 bits), TCP
  28.  * 'push' bit, and flags that indicate which of the 4 TCP sequence
  29.  * numbers have changed (bottom 5 bits).  The next octet is a
  30.  * conversation number that associates a saved IP/TCP header with
  31.  * the compressed packet.  The next two octets are the TCP checksum
  32.  * from the original datagram.    The next 0 to 15 octets are
  33.  * sequence number changes, one change per bit set in the header
  34.  * (there may be no changes and there are two special cases where
  35.  * the receiver implicitly knows what changed -- see below).
  36.  *
  37.  * There are 5 numbers which can change (they are always inserted
  38.  * in the following order): TCP urgent pointer, window,
  39.  * acknowlegement, sequence number and IP ID.  (The urgent pointer
  40.  * is different from the others in that its value is sent, not the
  41.  * change in value.)  Since typical use of SLIP links is biased
  42.  * toward small packets (see comments on MTU/MSS below), changes
  43.  * use a variable length coding with one octet for numbers in the
  44.  * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
  45.  * range 256 - 65535 or 0.  (If the change in sequence number or
  46.  * ack is more than 65535, an uncompressed packet is sent.)
  47.  */
  48.  
  49. /*
  50.  * Packet types (must not conflict with IP protocol version)
  51.  *
  52.  * The top nibble of the first octet is the packet type.  There are
  53.  * three possible types: IP (not proto TCP or tcp with one of the
  54.  * control flags set); uncompressed TCP (a normal IP/TCP packet but
  55.  * with the 8-bit protocol field replaced by an 8-bit connection id --
  56.  * this type of packet syncs the sender & receiver); and compressed
  57.  * TCP (described above).
  58.  *
  59.  * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
  60.  * is logically part of the 4-bit "changes" field that follows.  Top
  61.  * three bits are actual packet type.  For backward compatibility
  62.  * and in the interest of conserving bits, numbers are chosen so the
  63.  * IP protocol version number (4) which normally appears in this nibble
  64.  * means "IP packet".
  65.  */
  66.  
  67. typedef unsigned long  u_long;
  68. typedef unsigned int   u_int;
  69. typedef unsigned short u_short;
  70. typedef unsigned char  u_char;
  71.  
  72. typedef unsigned short int16;
  73. typedef unsigned long int32;
  74.  
  75. /* IP and TCP header format */
  76.  
  77. struct ip_header {
  78.     char v_ihl;        /* Version + IP header length */
  79. #define IPVERSION    4
  80.     char tos;        /* Type of service */
  81.     int16 length;        /* Total length */
  82.     int16 id;        /* Identification */
  83.     int16 fl_offs;        /* Flags + fragment offset */
  84.  
  85. #define F_OFFSET    0x1fff    /* Offset field */
  86. #define DF    0x4000        /* Don't fragment flag */
  87. #define MF    0x2000        /* More Fragments flag */
  88.  
  89.     char ttl;        /* Time to live */
  90.     char protocol;        /* Protocol */
  91.     int16 checksum;     /* Header checksum */
  92.     int32 source;        /* Source address */
  93.     int32 dest;        /* Destination address */
  94. };
  95.  
  96. /* TCP segment header */
  97. struct tcp_header {
  98.     int16 source;    /* Source port */
  99.     int16 dest;    /* Destination port */
  100.     int32 seq;    /* Sequence number */
  101.     int32 ack;    /* Acknowledgment number */
  102.     char offset;    /* Data offset */
  103.     char flags;    /* Flags, data offset */
  104. #define DSHIFT    4    /* Data offset field */
  105. #define DMASK    0x0f    /* Mask for normalized data offset field */
  106. #define URG    0x20    /* URGent flag */
  107. #define ACK    0x10    /* ACKnowledgment flag */
  108. #define PSH    0x08    /* PuSH flag */
  109. #define RST    0x04    /* ReSeT flag */
  110. #define SYN    0x02    /* SYNchronize flag */
  111. #define FIN    0x01    /* FINal flag */
  112.     int16 wnd;    /* Receiver flow control window */
  113.     int16 checksum; /* Header + data checksum */
  114.     int16 up;    /* Urgent pointer */
  115. };
  116.  
  117. /* IP protocol field values */
  118. #define TCP_PTCL    6    /* Transmission Control Protocol */
  119.  
  120. #define lonibble(x)     ((x) & 0x0F)
  121.  
  122. struct mbuf {
  123.     u_char *m_off;    /* pointer to start of data */
  124.     int    m_len;    /* length of data */
  125. };
  126. #define mtod(m, t)      ((t)(m->m_off))
  127.  
  128. /* Appendix A.1  Definitions and State Data */
  129.  
  130. #define MAX_STATES    16    /* must be >2 and <255 */
  131. #define MAX_HDR     128    /* max TCP+IP hdr length (by protocol def) */
  132.  
  133. /* packet types */
  134. #define TYPE_IP     0x40
  135. #define TYPE_UNCOMPRESSED_TCP 0x70
  136. #define TYPE_COMPRESSED_TCP 0x80
  137. #define TYPE_ERROR    0x00    /* this is not a type that ever appears on
  138.                  * the wire. The receive framer uses it to
  139.                  * tell the decompressor there was a packet
  140.                  * transmission error. */
  141. /*
  142.  * Bits in the first octet of the compressed packet
  143.  */
  144.  
  145. /* flag bits for what changed in a packet */
  146.  
  147. #define NEW_C        0x40    /* Connection id */
  148. #define NEW_I        0x20    /* IP ID field (change != 1) */
  149. #define TCP_PUSH_BIT    0x10    /* TCP PUSH bit */
  150.  
  151. #define NEW_S        0x08    /* Sequence number */
  152. #define NEW_A        0x04    /* Acknowledgement */
  153. #define NEW_W        0x02    /* Window size */
  154. #define NEW_U        0x01    /* Urgent pointer */
  155.  
  156. /* reserved, special-case values of above */
  157.  
  158. #define SPECIAL_I    (NEW_S|NEW_W|NEW_U)     /* echoed interactive traffic */
  159. #define SPECIAL_D    (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
  160. #define SPECIALS_MASK    (NEW_S|NEW_A|NEW_W|NEW_U)
  161.  
  162. /*
  163.  * "state" data for each active tcp conversation on the wire. This is
  164.  * basically a copy of the entire TCP/IP header from the last packet together
  165.  * with a small identifier the transmit & receive ends of the line use to
  166.  * locate the saved header.
  167.  */
  168. struct cstate {
  169.     struct cstate *cs_next; /* next most recently used cstate (xmit only) */
  170.     u_short cs_hlen;    /* size of hdr (receive only) */
  171.     u_char cs_id;        /* connection # associated with this state */
  172.     u_char cs_filler;
  173.     union {
  174.         u_char csu_hdr[MAX_HDR];
  175.         int32 csu_hdr4[1];
  176.         struct ip_header csu_ip; /* ip/tcp hdr from most recent packet */
  177.     } slcs_u;
  178. };
  179. #define cs_ip        slcs_u.csu_ip
  180. #define cs_hdr        slcs_u.csu_hdr
  181. #define cs_hdr4     slcs_u.csu_hdr4
  182.  
  183. /*
  184.  * all the state data for one serial line (we need one of these per line).
  185.  */
  186. struct slcompress {
  187.     struct cstate *tstate;    /* transmit connection states (array)*/
  188.     struct cstate *rstate;    /* receive connection states (array)*/
  189.  
  190.     u_char tslot_limit;    /* highest transmit slot id (0-l)*/
  191.     u_char rslot_limit;    /* highest receive slot id (0-l)*/
  192.  
  193.     struct cstate *last_cs; /* most recently used tstate */
  194.     u_char last_recv;    /* last received connection id */
  195.     u_char last_xmit;    /* last sent connection id */
  196.     u_char flags;
  197.  
  198.     u_long sls_o_nontcp;    /* outbound non-TCP packets */
  199.     u_long sls_o_tcp;    /* outbound TCP packets */
  200.     u_long sls_o_uncompressed;    /* outbound uncompressed packets */
  201.     u_long sls_o_compressed;/* outbound compressed packets */
  202.     u_long sls_o_searches;    /* searches for connection state */
  203.     u_long sls_o_misses;    /* times couldn't find conn. state */
  204.  
  205.     u_long sls_i_ip;    /* inbound non-TCP packets */
  206.     u_long sls_i_uncompressed;    /* inbound uncompressed packets */
  207.     u_long sls_i_compressed;/* inbound compressed packets */
  208.     u_long sls_i_error;    /* inbound error packets */
  209.     u_long sls_i_tossed;    /* inbound packets tossed because of error */
  210.  
  211.     signed char on;     /* ==SL_ON: on, >0: trycount, ==0: off */
  212. };
  213.  
  214. /* last_xmit/last_recv initial value */
  215. #define NO_CID        255
  216.  
  217. /* flag values */
  218. #define SLF_TOSS    1    /* tossing rcvd frames because of input err */
  219. #define SLF_ALLOWED    2    /* allow receiving compression */
  220. #define SLF_ON        4    /* use compression */
  221.  
  222. /* optional trycount feature */
  223. #define TRYCOUNT    3    /* try 3 TCP_UNCOMPRESSED packets */
  224. #define SL_ON        -1    /* use compression */
  225.  
  226. /*
  227.  * The following macros are used to encode and decode numbers. They all
  228.  * assume that 'cp' points to a buffer where the next byte encoded (decoded)
  229.  * is to be stored (retrieved). Since the decode routines do arithmetic,
  230.  * they have to convert from and to network byte order.
  231.  */
  232.  
  233. /*
  234.  * ENCODE encodes a number that is known to be non-zero. ENCODEZ checks for
  235.  * zero (zero has to be encoded in the long, 3 byte form).
  236.  */
  237.  
  238. #define ENCODE(n) { \
  239.     if ((u_short)(n) >= 256) { \
  240.         *cp++ = 0; \
  241.         cp[1] = (n); \
  242.         cp[0] = (n) >> 8; \
  243.         cp += 2; \
  244.     } else { \
  245.         *cp++ = (n); \
  246.     } \
  247.     }
  248.  
  249. #define ENCODEZ(n) { \
  250.     if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
  251.         *cp++ = 0; \
  252.         cp[1] = (n); \
  253.         cp[0] = (n) >> 8; \
  254.         cp += 2; \
  255.     } else { \
  256.         *cp++ = (n); \
  257.     } \
  258.     }
  259.  
  260. /*
  261.  * DECODEL takes the compressed change at byte cp and adds it to the
  262.  * current value of packet field 'f' (which must be a 4-byte (long) integer
  263.  * in the current network byte order). DECODES does the same for a 2-byte (short)
  264.  * field. DECODEU takes the change at cp and stuffs it into the (short) field f.
  265.  * 'cp' is updated to point to the next field in the compressed header.
  266.  */
  267.  
  268. #define DECODEL(f) { \
  269.     if (*cp == 0) { \
  270.         (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
  271.         cp += 3; \
  272.     } else { \
  273.         (f) = htonl(ntohl(f) + (u_long)*cp++); \
  274.     } \
  275.     }
  276.  
  277. #define DECODES(f) { \
  278.     if (*cp == 0) { \
  279.         (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
  280.         cp += 3; \
  281.     } else { \
  282.         (f) = htons(ntohs(f) + (u_short)*cp++); \
  283.     } \
  284.     }
  285.  
  286. #define DECODEU(f) { \
  287.     if (*cp == 0) { \
  288.         (f) = htons(((cp[1] << 8) | cp[2])); \
  289.         cp += 3; \
  290.     } else { \
  291.         (f) = htons((u_short)*cp++); \
  292.     } \
  293.     }
  294.  
  295. #define BCOPY(s, d, l)  memcpy(d, s, l)
  296. #define BCMP(s, d, l)   memcmp(d, s, l)
  297.  
  298. #define htons(s)        (s)     /* on big-endian machines, that is */
  299. #define ntohs(s)        (s)
  300. #define htonl(l)        (l)
  301. #define ntohl(l)        (l)
  302.  
  303. /* Sana2 special stats values */
  304.  
  305. #define S2SS_CSLIP_O_NONTCP    ((S2WireType_CSLIP << 16) | 1)
  306. #define S2SS_CSLIP_O_TCP    ((S2WireType_CSLIP << 16) | 2)
  307. #define S2SS_CSLIP_O_UNCOMPRESSED   ((S2WireType_CSLIP << 16) | 3)
  308. #define S2SS_CSLIP_O_COMPRESSED ((S2WireType_CSLIP << 16) | 4)
  309. #define S2SS_CSLIP_O_SEARCHES    ((S2WireType_CSLIP << 16) | 5)
  310. #define S2SS_CSLIP_O_MISSES    ((S2WireType_CSLIP << 16) | 6)
  311.  
  312. #define S2SS_CSLIP_I_IP     ((S2WireType_CSLIP << 16) | 17)
  313. #define S2SS_CSLIP_I_UNCOMPRESSED   ((S2WireType_CSLIP << 16) | 18)
  314. #define S2SS_CSLIP_I_COMPRESSED ((S2WireType_CSLIP << 16) | 19)
  315. #define S2SS_CSLIP_I_ERROR    ((S2WireType_CSLIP << 16) | 20)
  316. #define S2SS_CSLIP_I_TOSSED    ((S2WireType_CSLIP << 16) | 21)
  317.  
  318. /* Prototypes for functions defined in cslip.c */
  319.  
  320. u_char sl_compress_tcp(struct mbuf *m, struct slcompress *comp);
  321. void sl_xmit_error(struct slcompress *comp);
  322. struct mbuf *sl_uncompress_tcp(struct mbuf *m, u_int type, struct slcompress *comp);
  323. void sl_compress_init(struct slcompress *comp, int, int);
  324. void sl_compress_deinit(struct slcompress *comp);
  325.  
  326.